ক্লোজারে (Clojure) ফাংশনাল প্রোগ্রামিংয়ের জন্য ফাংশন খুবই গুরুত্বপূর্ণ। ফাংশন ব্যবহার করে কোডকে পুনরায় ব্যবহারযোগ্য এবং সংক্ষিপ্ত রাখা যায়। ক্লোজারে ফাংশন ডিফাইন করা, কল করা, এবং হাই-অর্ডার ফাংশন ব্যবহার করা সহজ। এখানে ক্লোজারে ফাংশন সংক্রান্ত মূল ধারণাগুলো নিয়ে আলোচনা করা হলো।
ক্লোজারে ফাংশন ডেফিন করার জন্য defn
কীওয়ার্ড ব্যবহার করা হয়। defn
এর মাধ্যমে ফাংশনের নাম, আর্গুমেন্ট এবং ফাংশনের বডি নির্ধারণ করা হয়।
(defn যোগফল [a b]
(+ a b))
এখানে যোগফল
নামের একটি ফাংশন তৈরি করা হয়েছে, যা a
এবং b
নামক দুটি আর্গুমেন্ট নিয়ে তাদের যোগফল প্রদান করে।
উদাহরণ ফাংশন কল:
(যোগফল ৫ ৩) ; আউটপুট: ৮
ক্লোজারে ফাংশনে বিভিন্ন ধরনের আর্গুমেন্ট পাস করা যায়। একটি ফাংশন এক বা একাধিক আর্গুমেন্ট নিতে পারে।
(defn বর্গ [x]
(* x x))
(বর্গ ৪) ; আউটপুট: ১৬
এখানে বর্গ
নামের ফাংশনটি একটি সংখ্যা গ্রহণ করে তার বর্গফল প্রদান করে।
ক্লোজারে ফাংশনের ডিফল্ট আর্গুমেন্ট সরাসরি ব্যবহার করা সম্ভব নয়, তবে অপশনাল আর্গুমেন্ট পাস করতে ভ্যারিয়াডিক আর্গুমেন্ট ব্যবহার করা যায়।
ক্লোজারে &
চিহ্নের মাধ্যমে ভ্যারিয়াডিক আর্গুমেন্ট ব্যবহার করা যায়, যা অসীম সংখ্যক আর্গুমেন্ট গ্রহণ করে। উদাহরণস্বরূপ:
(defn যোগফল-সব [x & আরো]
(apply + x আরো))
(যোগফল-সব ১ ২ ৩ ৪) ; আউটপুট: ১০
এখানে যোগফল-সব
ফাংশনটি একাধিক আর্গুমেন্ট নিয়ে তাদের যোগফল প্রদান করে।
ক্লোজারে অ্যানোনিমাস ফাংশন তৈরি করার জন্য fn
বা #()
ব্যবহার করা হয়। এগুলো সাধারণত অস্থায়ী বা ছোট ফাংশনের জন্য ব্যবহার করা হয়।
fn
এর মাধ্যমে অ্যানোনিমাস ফাংশন:
((fn [x y] (+ x y)) ৫ ৩) ; আউটপুট: ৮
শর্টকাট #()
এর মাধ্যমে অ্যানোনিমাস ফাংশন:
(#(+ %1 %2) ৫ ৩) ; আউটপুট: ৮
এখানে %1
এবং %2
প্রথম ও দ্বিতীয় আর্গুমেন্টকে নির্দেশ করে।
ক্লোজারে ফাংশনকে আর্গুমেন্ট হিসেবে পাঠানো এবং ফাংশন থেকে ফাংশন ফেরত দেওয়া সম্ভব। এর মাধ্যমে হাই-অর্ডার ফাংশন তৈরি করা যায়।
উদাহরণ: map
ফাংশন:
(map #(* % %) [১ ২ ৩ ৪]) ; আউটপুট: (১ ৪ ৯ ১৬)
এখানে map
ফাংশনটি একটি ফাংশন এবং একটি ভেক্টর নেয় এবং প্রতিটি মানে ফাংশনটি প্রয়োগ করে।
উদাহরণ: filter
ফাংশন:
(filter odd? [১ ২ ৩ ৪]) ; আউটপুট: (১ ৩)
filter
ফাংশনটি একটি শর্ত ফাংশন এবং একটি কালেকশন নেয়, এবং শর্ত অনুযায়ী ফিল্টার করা মানগুলো ফেরত দেয়।
ক্লোজারে রিকার্সন ফাংশন ব্যবহার করা হয় যেখানে loop
এবং recur
দ্বারা কার্যকরী রিকার্সন করা যায়।
উদাহরণ:
(defn factorial [n]
(loop [i n result 1]
(if (zero? i)
result
(recur (dec i) (* result i)))))
(factorial ৫) ; আউটপুট: ১২০
এখানে, factorial
ফাংশনটি একটি লুপ তৈরি করে এবং recur
ব্যবহার করে পুনরাবৃত্তি করে ফ্যাক্টরিয়াল গণনা করে।
ক্লোজারে বিভিন্ন ফাংশন একত্রে কম্পোজ করা যায়। comp
ফাংশনটি বিভিন্ন ফাংশনকে চেইন করে কার্যকরী কম্পোজিশন তৈরি করে।
(defn বর্গ [x] (* x x))
(defn যোগ-দুই [x] (+ x ২))
((comp যোগ-দুই বর্গ) ৩) ; আউটপুট: ১১
এখানে, comp
প্রথমে বর্গ
ফাংশন প্রয়োগ করে এবং তারপর যোগ-দুই
ফাংশন প্রয়োগ করে।
ক্লোজারে ম্যাক্রো ফাংশন ব্যবহার করা যায় যা কোড ম্যানিপুলেট করতে পারে। ম্যাক্রো ফাংশনগুলি ক্লোজারে মেটাপ্রোগ্রামিং এর জন্য ব্যবহৃত হয়। ম্যাক্রো ফাংশন তৈরি করতে defmacro
ব্যবহার করা হয়।
(defmacro unless [condition body]
`(if (not ~condition) ~body))
(unless false (println "This will print!"))
; আউটপুট: This will print!
ক্লোজারে ফাংশন ডেফিনিশন থেকে শুরু করে রিকার্সন, হাই-অর্ডার ফাংশন, ভ্যারিয়াডিক ফাংশন এবং ম্যাক্রো পর্যন্ত অনেক ধরনের ফাংশন রয়েছে। এই বৈশিষ্ট্যগুলো ক্লোজারের ফাংশনাল প্রোগ্রামিংয়ের ক্ষমতাকে আরও উন্নত করে এবং বড় প্রজেক্টেও কার্যকরভাবে ব্যবহৃত হয়।
defn
এবং Anonymous Functions (fn
)Clojure এ ফাংশন ডিক্লারেশন করার দুটি প্রধান পদ্ধতি আছে: defn
এবং অজানা ফাংশন (Anonymous Functions), যা fn
ব্যবহার করে তৈরি করা হয়। defn
মূলত নামযুক্ত ফাংশন তৈরি করতে ব্যবহৃত হয়, যেখানে অজানা ফাংশনগুলি সাধারণত এককালীন বা কনটেক্সচুয়াল কাজে ব্যবহৃত হয়।
defn
- Named Function DeclarationClojure-এ defn
কীওয়ার্ড ব্যবহার করে একটি নামযুক্ত ফাংশন ডিক্লারেশন করা যায়। এটি একটি পরিচিত পদ্ধতি, যেখানে ফাংশনের নাম এবং এর প্যারামিটারগুলি নির্ধারণ করা হয়।
defn
এর সাধারণ সিনট্যাক্স(defn function-name
"Optional docstring explaining the function"
[param1 param2 ...]
(expression-to-evaluate))
(defn যোগফল
"দুটি সংখ্যার যোগফল প্রদান করে"
[a b]
(+ a b))
(যোগফল ৫ ১০) ; আউটপুট: ১৫
এখানে, যোগফল
নামে একটি ফাংশন ডিক্লেয়ার করা হয়েছে যা দুইটি প্যারামিটার গ্রহণ করে এবং তাদের যোগফল প্রদান করে।
Clojure এ defn
ফাংশনে একাধিক প্যারামিটার ভ্যারিয়েন্ট যুক্ত করা যায়, যা বিভিন্ন সংখ্যক আর্গুমেন্ট গ্রহণ করতে পারে।
(defn যোগফল
([a] a)
([a b] (+ a b))
([a b c] (+ a b c)))
(যোগফল ১০) ; আউটপুট: ১০
(যোগফল ৫ ১৫) ; আউটপুট: ২০
(যোগফল ১ ২ ৩) ; আউটপুট: ৬
এখানে, যোগফল
ফাংশন বিভিন্ন সংখ্যক আর্গুমেন্ট গ্রহণ করতে সক্ষম।
fn
)Anonymous Functions বা অজানা ফাংশনগুলি এককালীন কাজে ব্যবহৃত হয় এবং কোনো নির্দিষ্ট নাম থাকে না। সাধারণত সংক্ষিপ্ত ও কনটেক্সট-ভিত্তিক কাজের জন্য এই ফাংশনগুলি ব্যবহৃত হয়।
fn
এর সাধারণ সিনট্যাক্স(fn [param1 param2 ...]
(expression-to-evaluate))
((fn [x y] (+ x y)) ১০ ২০) ; আউটপুট: ৩০
এখানে (fn [x y] (+ x y))
একটি অজানা ফাংশন, যা দুইটি আর্গুমেন্টের যোগফল প্রদান করে এবং নাম ছাড়াই সরাসরি কল করা হয়েছে।
#()
Clojure এ অজানা ফাংশনের জন্য শর্টকাট সিনট্যাক্স #()
ব্যবহার করা যায়। এটি এক বা দুই লাইনের ফাংশনের জন্য সুবিধাজনক। #
চিহ্ন দিয়ে শুরু করে প্যারামিটার %
দিয়ে প্রকাশ করা হয়।
(#(+ %1 %2) ১০ ২০) ; আউটপুট: ৩০
এখানে, %1
এবং %2
যথাক্রমে প্রথম এবং দ্বিতীয় আর্গুমেন্ট হিসেবে ব্যবহৃত হয়েছে।
Anonymous Functions সাধারণত map
, filter
, এবং reduce
এর মতো হাই-অর্ডার ফাংশনগুলির সাথে ব্যবহৃত হয়।
(map (fn [x] (* x x)) [1 2 3 4]) ; আউটপুট: (1 4 9 16)
(map #(* % %) [1 2 3 4]) ; আউটপুট: (1 4 9 16)
এখানে, একটি অজানা ফাংশন প্রতিটি উপাদানকে তার বর্গফল প্রদান করে।
defn
: নামযুক্ত ফাংশন তৈরির জন্য ব্যবহৃত হয়, যেখানে ফাংশনের নাম এবং প্যারামিটার উল্লেখ করা হয়।fn
): এককালীন কাজের জন্য নামহীন ফাংশন ব্যবহৃত হয়, যা সরাসরি ব্যবহারযোগ্য।#()
: Anonymous Functions এর জন্য সংক্ষিপ্ত সিনট্যাক্স, যেখানে %
চিহ্ন দিয়ে প্যারামিটার প্রকাশ করা হয়।Clojure এ defn
এবং Anonymous Functions এর মাধ্যমে প্রোগ্রামিং আরও সংক্ষিপ্ত এবং কার্যকর হয়।
ক্লোজারে (Clojure) Higher-Order Functions (উচ্চ-স্তরের ফাংশন) এমন ফাংশন যেগুলো অন্যান্য ফাংশনকে আর্গুমেন্ট হিসেবে গ্রহণ করতে পারে অথবা একটি ফাংশনকে আউটপুট হিসেবে ফেরত দিতে পারে। এই ফাংশনগুলো ফাংশনাল প্রোগ্রামিংয়ের একটি মূল বৈশিষ্ট্য, যা কোডকে সংক্ষিপ্ত, পুনরায় ব্যবহারযোগ্য এবং আরও শক্তিশালী করে তোলে।
ক্লোজারে বেশ কয়েকটি বিল্ট-ইন Higher-Order Functions রয়েছে যা সাধারণত ব্যবহৃত হয়। এখানে কয়েকটি গুরুত্বপূর্ণ Higher-Order Functions এবং তাদের ব্যবহার দেখানো হলো:
map
একটি Higher-Order Function যা একটি ফাংশন এবং একটি কালেকশন গ্রহণ করে এবং প্রতিটি আইটেমের উপর ফাংশনটি প্রয়োগ করে একটি নতুন কালেকশন তৈরি করে। এটি কালেকশনের প্রতিটি উপাদানের উপর একই অপারেশন চালাতে ব্যবহৃত হয়।
ব্যবহার:
(map inc [1 2 3 4 5])
; আউটপুট: (2 3 4 5 6)
(map #(* % 2) [1 2 3 4 5])
; আউটপুট: (2 4 6 8 10)
উপরের উদাহরণে, map
ফাংশনটি inc
(increment) ফাংশনকে প্রতিটি উপাদানের উপর প্রয়োগ করে এবং একে নতুনভাবে সাজায়।
filter
ফাংশনটি একটি প্রেডিকেট ফাংশন এবং একটি কালেকশন গ্রহণ করে এবং প্রেডিকেট সত্য হলে কেবল সেই উপাদানগুলো ফেরত দেয়। এটি সাধারণত কালেকশন থেকে নির্দিষ্ট উপাদানগুলো বের করতে ব্যবহৃত হয়।
ব্যবহার:
(filter even? [1 2 3 4 5 6])
; আউটপুট: (2 4 6)
(filter #(> % 3) [1 2 3 4 5])
; আউটপুট: (4 5)
এখানে, filter
ফাংশনটি কেবল সেই মানগুলো রাখছে যা even?
(জোড় সংখ্যা) বা > 3
শর্ত পূরণ করে।
reduce
ফাংশনটি একটি ফাংশন, একটি ইনিশিয়াল ভ্যালু (বিকল্প) এবং একটি কালেকশন গ্রহণ করে। এটি কালেকশনের উপাদানগুলোকে নির্দিষ্ট ফাংশনের সাহায্যে একীভূত করে একটি একক মান প্রদান করে। এটি সাধারণত সমষ্টি, গুণ বা কাস্টম একীভূত ক্রিয়ার জন্য ব্যবহৃত হয়।
ব্যবহার:
(reduce + [1 2 3 4 5])
; আউটপুট: 15
(reduce * 1 [1 2 3 4 5])
; আউটপুট: 120
এখানে, reduce
ফাংশনটি প্রথম উদাহরণে সমস্ত উপাদানের যোগফল এবং দ্বিতীয় উদাহরণে গুণফল প্রদান করে।
apply
ফাংশনটি একটি ফাংশন এবং একটি কালেকশন গ্রহণ করে এবং কালেকশনের প্রতিটি উপাদানকে ফাংশনের আর্গুমেন্ট হিসেবে প্রয়োগ করে। এটি তখন ব্যবহৃত হয় যখন আপনি একটি কালেকশনকে একসাথে ফাংশনের আর্গুমেন্ট হিসেবে ব্যবহার করতে চান।
ব্যবহার:
(apply + [1 2 3 4 5])
; আউটপুট: 15
(apply max [10 20 30 5])
; আউটপুট: 30
এখানে, apply
ফাংশনটি [1 2 3 4 5]
-এর উপাদানগুলোকে +
ফাংশনে আর্গুমেন্ট হিসেবে প্রয়োগ করে এবং যোগফল দেয়।
comp
ফাংশনটি একাধিক ফাংশনকে একত্রে কম্পোজ করে একটি নতুন ফাংশন তৈরি করে। এই নতুন ফাংশনটি ফাংশনগুলোর ক্রমানুসারে একের পর এক প্রয়োগ করা হয়।
ব্যবহার:
(def increment-and-double (comp #(* % 2) inc))
(increment-and-double 3)
; আউটপুট: 8
এখানে, increment-and-double
ফাংশনটি প্রথমে inc
(increment) ফাংশন এবং তারপর (* % 2)
(double) ফাংশনকে প্রয়োগ করে।
partial
ফাংশনটি একটি ফাংশন এবং কিছু আর্গুমেন্ট গ্রহণ করে এবং নতুন একটি ফাংশন তৈরি করে যেখানে সেই আর্গুমেন্টগুলো ইতিমধ্যে প্রয়োগ করা থাকে। এটি সাধারণত ফাংশন তৈরি করতে ব্যবহৃত হয় যা পূর্ব-নির্ধারিত আর্গুমেন্ট সহ ব্যবহারযোগ্য।
ব্যবহার:
(def add-five (partial + 5))
(add-five 10)
; আউটপুট: 15
এখানে, add-five
ফাংশনটি +
ফাংশনের একটি পার্শিয়াল এপ্লিকেশন, যেখানে প্রথম আর্গুমেন্ট হিসেবে ৫ নির্ধারিত আছে।
Higher-Order Functions প্রোগ্রামিংকে আরও সংক্ষিপ্ত, পুনঃব্যবহারযোগ্য এবং কার্যকর করে। এগুলো ব্যবহার করে জটিল অপারেশনকে সহজে ভেঙে ফেলা যায় এবং প্রতিটি অপারেশন নির্দিষ্ট ফাংশনের মাধ্যমে স্পষ্টভাবে সংজ্ঞায়িত হয়। এছাড়াও, ফাংশনগুলোকে আর্গুমেন্ট হিসেবে পাস করে ক্লোজারে ফাংশনাল প্রোগ্রামিংয়ের ক্ষমতা আরও বাড়ানো যায়।
map
এবং filter
ব্যবহার করে ডেটাকে সহজে ট্রান্সফর্ম এবং ফিল্টার করা যায়।comp
ব্যবহার করে একাধিক ফাংশনকে একত্রে সংযুক্ত করা যায়, যা কোড পুনরায় ব্যবহারে সহায়ক।Higher-Order Functions ব্যবহার করে, ক্লোজারে ফাংশনাল প্রোগ্রামিং আরো শক্তিশালী এবং সৃজনশীল হয়, যা জটিল অপারেশন সহজ করে।
ফাংশনাল প্রোগ্রামিং ভাষা হিসেবে ক্লোজারে (Clojure) ফাংশন কম্পোজিশন এবং পার্শিয়াল অ্যাপ্লিকেশন খুবই গুরুত্বপূর্ণ এবং শক্তিশালী কনসেপ্ট, যা ফাংশনাল প্রোগ্রামিংকে আরও কার্যকর এবং সংক্ষিপ্ত করে তোলে। ফাংশন কম্পোজিশন এবং পার্শিয়াল অ্যাপ্লিকেশন ডেভেলপারদের ফাংশন তৈরি এবং পুনরায় ব্যবহারযোগ্যতা বাড়াতে সাহায্য করে।
ফাংশন কম্পোজিশন হলো দুটি বা ততোধিক ফাংশনকে একত্রিত করে একটি নতুন ফাংশন তৈরি করা। এতে একটি ফাংশনের আউটপুট অন্য একটি ফাংশনের ইনপুট হিসেবে ব্যবহৃত হয়। ক্লোজারে comp
ফাংশন ব্যবহার করে ফাংশন কম্পোজিশন করা যায়।
ধরা যাক, আমরা দুটি ফাংশন square
এবং increment
তৈরি করতে চাই, যেখানে একটি সংখ্যার বর্গফল বের করা হয় এবং এরপর সেই ফলাফলে ১ যোগ করা হয়।
(defn square [x]
(* x x))
(defn increment [x]
(+ x 1))
; ফাংশন কম্পোজিশনের মাধ্যমে নতুন ফাংশন তৈরি করা
(def composed-fn (comp increment square))
(composed-fn 4) ; আউটপুট: 17
এখানে, composed-fn
নামের নতুন ফাংশন তৈরি করা হয়েছে, যা প্রথমে square
ফাংশন চালায় এবং তারপর increment
ফাংশন চালায়। composed-fn
এ 4
পাস করলে প্রথমে বর্গফল 16
হয় এবং এরপর increment
ফাংশনে ১ যোগ করে 17
আউটপুট দেয়।
পার্শিয়াল অ্যাপ্লিকেশন হলো একটি ফাংশনের কিছু আর্গুমেন্ট ফিক্সড রেখে একটি নতুন ফাংশন তৈরি করা, যাতে পরবর্তীতে বাকি আর্গুমেন্ট দিয়ে ফাংশন চালানো যায়। ক্লোজারে partial
ফাংশন ব্যবহার করে পার্শিয়াল অ্যাপ্লিকেশন করা যায়।
ধরা যাক, আমাদের একটি ফাংশন আছে multiply
যা দুটি সংখ্যার গুণফল বের করে। আমরা এই ফাংশনের একটি আর্গুমেন্ট ফিক্সড রেখে নতুন একটি ফাংশন তৈরি করতে চাই।
(defn multiply [x y]
(* x y))
; পার্শিয়াল অ্যাপ্লিকেশন দিয়ে নতুন ফাংশন তৈরি
(def double (partial multiply 2))
(double 5) ; আউটপুট: 10
(double 10) ; আউটপুট: 20
এখানে partial
ফাংশন ব্যবহার করে multiply
ফাংশনের প্রথম আর্গুমেন্ট 2
ফিক্সড রাখা হয়েছে, ফলে নতুন ফাংশন double
তৈরি হয়েছে। এখন double
ফাংশন শুধু একটি আর্গুমেন্ট নেবে এবং এটিকে 2
এর সাথে গুণ করবে।
ফাংশন কম্পোজিশন এবং পার্শিয়াল অ্যাপ্লিকেশন একসাথে ব্যবহার করে শক্তিশালী ফাংশন তৈরি করা যায়।
ধরা যাক, আমাদের দুটি ফাংশন আছে - একটির কাজ সংখ্যাকে ১০ দিয়ে গুণ করা এবং অন্যটি সংখ্যার উপর ৫ যোগ করা। আমরা একটি পার্শিয়াল অ্যাপ্লিকেশন ও ফাংশন কম্পোজিশন ব্যবহার করে নতুন ফাংশন তৈরি করতে পারি।
(defn add [x y]
(+ x y))
(defn multiply [x y]
(* x y))
; ১০ দিয়ে গুণ করার জন্য পার্শিয়াল অ্যাপ্লিকেশন
(def multiply-by-10 (partial multiply 10))
; ৫ যোগ করার জন্য পার্শিয়াল অ্যাপ্লিকেশন
(def add-5 (partial add 5))
; ফাংশন কম্পোজিশন ব্যবহার করে নতুন ফাংশন তৈরি
(def process-fn (comp add-5 multiply-by-10))
(process-fn 3) ; আউটপুট: 35
এখানে, process-fn
ফাংশন প্রথমে multiply-by-10
চালায় এবং তারপর add-5
চালায়। ফলে (3 * 10) + 5 = 35
আউটপুট আসে।
কনসেপ্ট | বর্ণনা | ক্লোজারে ফাংশন |
---|---|---|
ফাংশন কম্পোজিশন | দুটি বা ততোধিক ফাংশনকে একত্রিত করে একটি নতুন ফাংশন তৈরি করা | comp |
পার্শিয়াল অ্যাপ্লিকেশন | ফাংশনের কিছু আর্গুমেন্ট ফিক্সড রেখে একটি নতুন ফাংশন তৈরি করা | partial |
ক্লোজারে ফাংশন কম্পোজিশন এবং পার্শিয়াল অ্যাপ্লিকেশন কোডকে সংক্ষিপ্ত, পুনরায় ব্যবহারযোগ্য এবং কার্যকরী করে তোলে। এগুলোর মাধ্যমে ডেভেলপাররা কম্পোজেবল ফাংশন তৈরি করতে পারেন, যা প্রোগ্রামের মডুলারিটি বাড়ায় এবং কোড মেইনটেনেন্স সহজ করে।
ক্লোজারে (Clojure) এবং অন্যান্য ফাংশনাল প্রোগ্রামিং ভাষায় রিকার্সন (Recursion) খুবই গুরুত্বপূর্ণ একটি কনসেপ্ট। এটি এমন একটি পদ্ধতি যেখানে একটি ফাংশন নিজেই নিজেকে কল করে একটি নির্দিষ্ট শর্ত পূরণ না হওয়া পর্যন্ত। তদ্ব্যতীত, টেইল রিকার্সন (Tail Recursion) রিকার্সনের একটি বিশেষ রূপ, যা কার্যক্ষমতাকে উন্নত করতে সাহায্য করে।
রিকার্সন হল এমন একটি প্রোগ্রামিং পদ্ধতি, যেখানে একটি ফাংশন নিজেই নিজেকে কল করে, এবং প্রতিবারই একটি নির্দিষ্ট শর্তের ভিত্তিতে নিজেকে পুনরাবৃত্তি করে। রিকার্সন সাধারণত তখন ব্যবহার করা হয় যখন সমস্যা একটি নির্দিষ্ট অংশে বিভক্ত করা যায় এবং প্রতিটি অংশে একই লজিক প্রয়োগ করা যায়।
নিচের উদাহরণে, একটি ফাংশন factorial
তৈরি করা হয়েছে, যা রিকার্সন ব্যবহার করে একটি সংখ্যার ফ্যাক্টরিয়াল গণনা করে:
(defn factorial [n]
(if (<= n 1)
1
(* n (factorial (dec n)))))
এখানে, factorial
ফাংশনটি নিজেই নিজেকে কল করে যতক্ষণ না n
এর মান 1
বা তার চেয়ে কম হয়। এই ফাংশনটি n
এর মানকে প্রতিবার 1
করে কমায় এবং শেষ পর্যন্ত ফ্যাক্টরিয়াল রিটার্ন করে।
টেইল রিকার্সন একটি বিশেষ ধরনের রিকার্সন, যেখানে ফাংশন কলের শেষে কোনো অতিরিক্ত অপারেশন নেই। এতে প্রতিটি রিকার্সিভ কল ফাংশনের শেষ অপারেশন হিসেবে কাজ করে, অর্থাৎ, এর পরে আর কোনো অপারেশন সম্পন্ন হয় না। এই ধরনের রিকার্সনে স্ট্যাকের ওপর অতিরিক্ত মেমোরি লোড পড়ে না, এবং কার্যক্ষমতা বৃদ্ধি পায়।
recur
ব্যবহারক্লোজারে টেইল রিকার্সন বাস্তবায়নের জন্য recur
কীওয়ার্ড ব্যবহার করা হয়। recur
রিকার্সিভ কলের ক্ষেত্রে লুপ হিসেবে কাজ করে এবং নতুন স্ট্যাক ফ্রেম তৈরি না করে পূর্বের ফ্রেমটি পুনরায় ব্যবহার করে, যা মেমোরি সাশ্রয় করে।
(defn factorial [n]
(let [helper (fn [n acc]
(if (<= n 1)
acc
(recur (dec n) (* acc n))))]
(helper n 1)))
এই উদাহরণে helper
নামের একটি অভ্যন্তরীণ ফাংশন ব্যবহার করা হয়েছে, যা recur
দিয়ে টেইল রিকার্সন কার্যকর করে। এখানে acc
(accumulator) প্যারামিটারটি ফলাফলের জন্য ব্যবহৃত হয়, এবং প্রতিটি রিকার্সিভ কলের শেষে recur
স্ট্যাকের লোড না বাড়িয়ে একই স্ট্যাক ফ্রেমে পুনরাবৃত্তি করে।
বৈশিষ্ট্য | রিকার্সন | টেইল রিকার্সন |
---|---|---|
স্ট্যাক ব্যবস্থাপনা | প্রতিটি কলে নতুন স্ট্যাক ফ্রেম তৈরি হয় | একই স্ট্যাক ফ্রেম পুনরায় ব্যবহার করে |
কার্যক্ষমতা | উচ্চ রিকার্সিভ স্তরে স্ট্যাক ওভারফ্লো ঝুঁকি থাকে | কার্যক্ষমতা বেশি, কারণ মেমোরি সাশ্রয়ী |
কোডের সরলতা | সরল এবং সহজে লেখা যায় | কিছুটা জটিল হতে পারে, বিশেষত অ্যাকিউমুলেটর ব্যবহারে |
নিচে দুটি পদ্ধতিতে ফিবোনাচি সিরিজ গণনার উদাহরণ দেওয়া হলো - সাধারণ রিকার্সন এবং টেইল রিকার্সন:
(defn fibonacci [n]
(if (<= n 1)
n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
এই ফাংশনটি প্রতিটি রিকার্সিভ কলের জন্য নতুন ফ্রেম তৈরি করে, যা বড় n
এর জন্য স্ট্যাক ওভারফ্লো ঘটাতে পারে।
(defn fibonacci [n]
(let [helper (fn [a b n]
(if (zero? n)
a
(recur b (+ a b) (dec n))))]
(helper 0 1 n)))
এই উদাহরণে helper
ফাংশনের মধ্যে recur
ব্যবহার করা হয়েছে, যা টেইল রিকার্সনের মাধ্যমে একই স্ট্যাক ফ্রেমে কার্যকর হয় এবং মেমোরি সাশ্রয় করে।
recur
ক্লোজারে টেইল রিকার্সন বাস্তবায়নের জন্য ব্যবহৃত হয়, যা নতুন স্ট্যাক ফ্রেম তৈরি না করে একই ফ্রেম পুনরায় ব্যবহার করে।ক্লোজারে কার্যক্ষমতা বৃদ্ধির জন্য টেইল রিকার্সন একটি শক্তিশালী কৌশল, বিশেষত বড় রিকার্সিভ অপারেশনের জন্য।
common.read_more